package net.zbus.proxy.trade;

import java.io.UnsupportedEncodingException;

import net.zbus.BusClient;
import net.zbus.ClientPool;
import net.zbus.ZBusException;
import net.zbus.ZMsg;



public class TradeClient{ 
	private ClientPool clientPool;

	private String service = "Trade";
	private String token = "";
	private int timeout = 2500;
	
	private String cryptService = "Utils";
	private String cryptToken = "";
	private int cryptTimeout = 2500; //ms
	public static final String DEFAULT_ENCODING = "GBK";
	private String encoding = DEFAULT_ENCODING;

	public String getEncoding() {
		return encoding;
	} 
	public void setEncoding(String encoding) {
		this.encoding = encoding;
	}


	public TradeClient(ClientPool clientPool, String service) {
		this.clientPool = clientPool;
		this.service = service;
	}
	 
	
	/**
	 * @param algorithm AES or KDE
	 * @param password
	 * @param key
	 * @return
	 */
	public String encrypt(String algorithm, String password, String key){
		ZMsg msg = new ZMsg(); 
		msg.pushBack("encrypt");
		msg.pushBack(algorithm);
		msg.pushBack(password);
		msg.pushBack(key);
		 
		 
		BusClient client = null;
		try{
			client = this.clientPool.borrowClient();
			msg = client.request(cryptService, cryptToken, msg, cryptTimeout); 
		} catch (ZBusException e) { 
			throw new ZBusException("request time out, " + e.getMessage());
		} finally{
			if(client != null){
				this.clientPool.returnClient(client);
			}
		} 
		 
		String code = msg.popFrontStr();
		if(code.equals("200")){
			return new String(msg.getLast());
		}else {
			throw new RuntimeException(new String(msg.getLast()));
		} 
	}
	
	/**
	 * 
	 * @param algorithm WANGAN
	 * @param password
	 * @param key
	 * @return
	 */
	public String decrypt(String algorithm, String publicKey, String privateKey, String password){
		ZMsg msg = new ZMsg(); 
		msg.pushBack("decrypt");
		msg.pushBack(algorithm);
		msg.pushBack(publicKey);
		msg.pushBack(privateKey);
		msg.pushBack(password);
		 
		BusClient client = null;
		try{
			client = this.clientPool.borrowClient();
			msg = client.request(cryptService, cryptToken, msg, cryptTimeout); 
		} catch (ZBusException e) { 
			throw new ZBusException("request time out, " + e.getMessage());
		} finally{
			if(client != null){
				this.clientPool.returnClient(client);
			}
		}  
		
		String code = msg.popFrontStr();
		if(code.equals("200")){
			return new String(msg.getLast());
		}else {
			throw new RuntimeException(new String(msg.getLast()));
		} 
	}
	
	public Response trade(Request request){  
		ZMsg msg = new ZMsg(); 
		byte[] reqBytes;
		try {
			reqBytes = request.toString().getBytes(this.encoding);
			msg.pushBack(reqBytes);
		} catch (UnsupportedEncodingException e1) { 
			e1.printStackTrace();
		}
		
		 
		BusClient client = null;
		try{
			client = this.clientPool.borrowClient();
			msg = client.request(service, token, msg, timeout); 
		} catch (ZBusException e) { 
			throw new ZBusException("request time out, " + e.getMessage());
		} finally{
			if(client != null){
				this.clientPool.returnClient(client);
			}
		} 
		
		Response response = new Response();
		String code = msg.popFrontStr();
		if(code.equals("200")){
			try {
				String res = new String(msg.getLast(), this.encoding);
				response = Response.load(res);
			} catch (UnsupportedEncodingException e) { 
				e.printStackTrace();
			}
			
		}else {
			throw new RuntimeException(new String(msg.getLast()));
		}
		return response; 
	}


	public String getService() {
		return service;
	}


	public void setService(String service) {
		this.service = service;
	}


	public String getToken() {
		return token;
	}


	public void setToken(String token) {
		this.token = token;
	}


	public int getTimeout() {
		return timeout;
	}


	public void setTimeout(int timeout) {
		this.timeout = timeout;
	}


	public String getCryptService() {
		return cryptService;
	}


	public void setCryptService(String cryptService) {
		this.cryptService = cryptService;
	}


	public String getCryptToken() {
		return cryptToken;
	}


	public void setCryptToken(String cryptToken) {
		this.cryptToken = cryptToken;
	}


	public int getCryptTimeout() {
		return cryptTimeout;
	}


	public void setCryptTimeout(int cryptTimeout) {
		this.cryptTimeout = cryptTimeout;
	} 
}

